package com.liruo.learn.spring.mvc.enumconverter.jacksondeprecated;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.liruo.learn.spring.mvc.enumconverter.SourceEnum;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;

public class SourceEnumDeserializer<S, T extends SourceEnum<S>> extends JsonDeserializer<T> implements ContextualDeserializer {

    private Class<T> enumClass;
    public SourceEnumDeserializer() {
    }

    public SourceEnumDeserializer(Class<T> enumClass) {
        this.enumClass = enumClass;
//        enumMap = Arrays.stream(enumClass.getEnumConstants())
//                .collect(Collectors.toMap(SourceEnum::getSource, Function.identity()));
    }

    @Override
    public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        Object source = jsonParser.readValueAs(Object.class);
        for (T enumeration : this.enumClass.getEnumConstants()){
            if(enumeration.getSource().equals(source)){
                return enumeration;
            }
        }
        return null;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        Class<?> clazz = property.getType().getRawClass();
        if (SourceEnum.class.isAssignableFrom(clazz)) {
            @SuppressWarnings("unchecked")
            Class<T> enumClass = (Class<T>) ((ParameterizedType) clazz.getGenericInterfaces()[0]).getActualTypeArguments()[0];
            return new SourceEnumDeserializer<>(enumClass);
        }
        return null;
    }
}
